TypeScriptμ κ°λ ₯ν νμ μμ μ±μΌλ‘ λ¬Έμ μ²λ¦¬ μν¬νλ‘μ°λ₯Ό κ°μ νμΈμ. λ€μν μ ν리μΌμ΄μ μμ νμΌ κ΄λ¦¬μ μμ μ±κ³Ό ν¨μ¨μ±μ λ°°μ°μΈμ.
TypeScript λ¬Έμ μ²λ¦¬: νμΌ κ΄λ¦¬ νμ μμ μ± λ§μ€ν°νκΈ°
νλ μννΈμ¨μ΄ κ°λ° λΆμΌμμ ν¨μ¨μ μ΄κ³ μμ ν νμΌ κ΄λ¦¬λ λ§€μ° μ€μν©λλ€. μΉ μ ν리μΌμ΄μ , λ°μ΄ν° μ²λ¦¬ νμ΄νλΌμΈ λλ μν°νλΌμ΄μ¦ λ 벨 μμ€ν μ ꡬμΆνλ , λ¬Έμ, κ΅¬μ± λ° κΈ°ν νμΌ κΈ°λ° μμ°μ μμ μ μΌλ‘ μ²λ¦¬νλ λ₯λ ₯μ νμμ μ λλ€. κΈ°μ‘΄ λ°©μμ λμ¨ν νμ΄νκ³Ό μλ μ ν¨μ± κ²μ¬λ‘ μΈν΄ λ°νμ μ€λ₯, λ°μ΄ν° μμ λ° λ³΄μ μΉ¨ν΄μ μ·¨μ½ν΄μ§λ κ²½μ°κ° λ§μ΅λλ€. μ΄λ κ°λ ₯ν νμ μμ€ν μ κ°μΆ TypeScriptκ° λΉμ λ°νλ κ³³μΌλ‘, νμ μΆμ’ μ λΆννλ νμΌ κ΄λ¦¬ νμ μμ μ±μ λ¬μ±νκΈ° μν κ°λ ₯ν μ루μ μ μ 곡ν©λλ€.
μ΄ ν¬κ΄μ μΈ κ°μ΄λλ μμ νκ³ ν¨μ¨μ μΈ λ¬Έμ μ²λ¦¬ λ° νμΌ κ΄λ¦¬λ₯Ό μν΄ TypeScriptλ₯Ό νμ©νλ 볡μ‘μ±μ λν΄ μμΈν μ€λͺ ν©λλ€. νμ μ μ, κ°λ ₯ν μ€λ₯ μ²λ¦¬ λ° λͺ¨λ² μ¬λ‘κ° λ²κ·Έλ₯Ό ν¬κ² μ€μ΄κ³ , κ°λ°μ μμ°μ±μ ν₯μμν€λ©°, μ§λ¦¬μ μμΉλ νμ λ€μμ±κ³Ό κ΄κ³μμ΄ λ°μ΄ν°μ 무결μ±μ 보μ₯νλ λ°©λ²μ μ΄ν΄λ³΄κ² μ΅λλ€.
νμΌ κ΄λ¦¬μμ νμ μμ μ±μ νμ
νμΌ κ΄λ¦¬λ λ³Έμ§μ μΌλ‘ 볡μ‘ν©λλ€. μ΄μ 체μ μ μνΈ μμ©νκ³ , λ€μν νμΌ νμ(μ: JSON, CSV, XML, μΌλ° ν μ€νΈ)μ μ²λ¦¬νκ³ , κΆνμ κ΄λ¦¬νκ³ , λΉλκΈ° μμ μ μ²λ¦¬νλ©°, μ μ¬μ μΌλ‘ ν΄λΌμ°λ μ€ν λ¦¬μ§ μλΉμ€μ ν΅ν©νλ κ²μ΄ ν¬ν¨λ©λλ€. κ°λ ₯ν νμ΄ν κ·μ¨μ΄ μμΌλ©΄ λͺ κ°μ§ μΌλ°μ μΈ ν¨μ μ΄ λνλ μ μμ΅λλ€.
- μμμΉ λͺ»ν λ°μ΄ν° ꡬ쑰: νμΌμ νμ±ν λ, νΉν κ΅¬μ± νμΌμ΄λ μ¬μ©μκ° μ λ‘λν μ½ν μΈ λ₯Ό νμ±ν λ νΉμ λ°μ΄ν° ꡬ쑰λ₯Ό κ°μ νλ©΄ μ€μ κ΅¬μ‘°κ° λ²μ΄λλ κ²½μ° λ°νμ μ€λ₯κ° λ°μν μ μμ΅λλ€. TypeScriptμ μΈν°νμ΄μ€μ νμ μ μ΄λ¬ν ꡬ쑰λ₯Ό μ μ©νμ¬ μμμΉ λͺ»ν λμμ λ°©μ§ν μ μμ΅λλ€.
- μλͺ»λ νμΌ κ²½λ‘: νμΌ κ²½λ‘μ μ€ν λλ μλ‘ λ€λ₯Έ μ΄μ 체μ μμ μλͺ»λ κ²½λ‘ κ΅¬λΆ κΈ°νΈλ₯Ό μ¬μ©νλ©΄ μ ν리μΌμ΄μ μ΄ μ€ν¨ν μ μμ΅λλ€. νμ μμ ν κ²½λ‘ μ²λ¦¬λ μ΄λ₯Ό μνν μ μμ΅λλ€.
- μΌκ΄μ± μλ λ°μ΄ν° νμ : νμΌμμ λ°μ΄ν°λ₯Ό μ½μ λ λ¬Έμμ΄μ μ«μλ‘ μ·¨κΈνκ±°λ κ·Έ λ°λλ‘ μ·¨κΈνλ κ²μ λ²κ·Έμ λΉλ²ν μμΈμ λλ€. TypeScriptμ μ μ νμ΄νμ μ»΄νμΌ μκ°μ μ΄λ¬ν λΆμΌμΉλ₯Ό ν¬μ°©ν©λλ€.
- 보μ μ·¨μ½μ : νμΌ μ λ‘λ λλ μ‘μΈμ€ μ μ΄λ₯Ό λΆμ μ νκ² μ²λ¦¬νλ©΄ μ£Όμ 곡격 λλ λ¬΄λ¨ λ°μ΄ν° λ ΈμΆλ‘ μ΄μ΄μ§ μ μμ΅λλ€. TypeScriptκ° λͺ¨λ 보μ λ¬Έμ λ₯Ό μ§μ ν΄κ²°νμ§λ μμ§λ§, νμ μμ ν κΈ°λ°μ μμ ν ν¨ν΄μ ꡬννλ λ° λμμ΄ λ©λλ€.
- μ μ§ κ΄λ¦¬μ± λ° κ°λ μ± λΆλ: λͺ νν νμ μ μκ° μλ μ½λλ² μ΄μ€λ νΉν ν¬κ³ μ μΈκ³μ μΌλ‘ λΆμ°λ νμμ μ΄ν΄, 리ν©ν λ§ λ° μ μ§ κ΄λ¦¬κ° μ΄λ ΅μ΅λλ€.
TypeScriptλ JavaScriptμ μ μ νμ΄νμ λμ νμ¬ μ΄λ¬ν κ³Όμ λ₯Ό ν΄κ²°ν©λλ€. μ¦, μ»΄νμΌ μ νμ κ²μ¬κ° μνλμ΄ μ½λκ° μ€νλκΈ°λ μ μ λ§μ μ μ¬μ μ€λ₯λ₯Ό ν¬μ°©ν©λλ€. νμΌ κ΄λ¦¬μ κ²½μ°, μ΄λ λ μμ μ μΈ μ½λ, λ μ μ λλ²κΉ μΈμ λ° λ μμΈ‘ κ°λ₯ν κ°λ° κ²½νμΌλ‘ μ΄μ΄μ§λλ€.
νμΌ μμ μ TypeScript νμ© (Node.js μμ )
Node.jsλ μλ² μΈ‘ μ ν리μΌμ΄μ μ ꡬμΆνκΈ° μν μΈκΈ° μλ λ°νμ νκ²½μ΄λ©°, λ΄μ₯λ `fs` λͺ¨λμ νμΌ μμ€ν μμ μ μ΄μμ λλ€. TypeScriptλ₯Ό Node.jsμ ν¨κ» μ¬μ©νλ©΄ `fs` λͺ¨λμ μ μ©μ±κ³Ό μμ μ±μ ν₯μμν¬ μ μμ΅λλ€.
μΈν°νμ΄μ€λ‘ νμΌ κ΅¬μ‘° μ μνκΈ°
μΌλ°μ μΈ μλ리μ€λ₯Ό κ³ λ €ν΄ λ³΄κ² μ΅λλ€. κ΅¬μ± νμΌμ μ½κ³ μ²λ¦¬ν©λλ€. TypeScript μΈν°νμ΄μ€λ₯Ό μ¬μ©νμ¬ μ΄ κ΅¬μ± νμΌμ μμ ꡬ쑰λ₯Ό μ μν μ μμ΅λλ€.
μμ: `config.interface.ts`
export interface ServerConfig {
port: number;
hostname: string;
database: DatabaseConfig;
logging: LoggingConfig;
}
interface DatabaseConfig {
type: 'postgres' | 'mysql' | 'mongodb';
connectionString: string;
}
interface LoggingConfig {
level: 'debug' | 'info' | 'warn' | 'error';
filePath?: string; // Optional file path for logs
}
μ΄ μμ μμλ μλ² κ΅¬μ±μ λν λͺ νν ꡬ쑰λ₯Ό μ μνμ΅λλ€. `port`λ μ«μμ¬μΌ νκ³ , `hostname`μ λ¬Έμμ΄μ΄μ΄μΌ νλ©°, `database` λ° `logging`μ ν΄λΉ μΈν°νμ΄μ€ μ μλ₯Ό μ€μν΄μΌ ν©λλ€. λ°μ΄ν°λ² μ΄μ€μ `type` μμ±μ νΉμ λ¬Έμμ΄ λ¦¬ν°λ΄λ‘ μ νλλ©°, `filePath`λ μ ν μ¬νμΌλ‘ νμλ©λλ€.
κ΅¬μ± νμΌ μ½κΈ° λ° μ ν¨μ± κ²μ¬
μ΄μ κ΅¬μ± νμΌμ μ½κ³ μ ν¨μ±μ κ²μ¬νλ TypeScript ν¨μλ₯Ό μμ±ν΄ λ³΄κ² μ΅λλ€. `fs` λͺ¨λκ³Ό κ°λ¨ν νμ μ΄μ€μ μ μ¬μ©νμ§λ§, λ³΄λ€ κ°λ ₯ν μ ν¨μ± κ²μ¬λ₯Ό μν΄ Zod λλ Yupκ³Ό κ°μ λΌμ΄λΈλ¬λ¦¬λ₯Ό κ³ λ €νμμμ€.
μμ: `configService.ts`
import * as fs from 'fs';
import * as path from 'path';
import { ServerConfig } from './config.interface';
const configFilePath = path.join(__dirname, '..', 'config.json'); // Assuming config.json is one directory up
export function loadConfig(): ServerConfig {
try {
const rawConfig = fs.readFileSync(configFilePath, 'utf-8');
const parsedConfig = JSON.parse(rawConfig);
// Basic type assertion. For production, consider runtime validation.
// This ensures that if the structure is wrong, TypeScript will complain.
const typedConfig = parsedConfig as ServerConfig;
// Further runtime validation can be added here for critical properties.
if (typeof typedConfig.port !== 'number' || typedConfig.port <= 0) {
throw new Error('Invalid server port configured.');
}
if (!typedConfig.hostname || typedConfig.hostname.length === 0) {
throw new Error('Server hostname is required.');
}
// ... add more validation as needed for database and logging configs
return typedConfig;
} catch (error) {
console.error(`Failed to load configuration from ${configFilePath}:`, error);
// Depending on your application, you might want to exit, use defaults, or re-throw.
throw new Error('Configuration loading failed.');
}
}
// Example of how to use it:
// try {
// const config = loadConfig();
// console.log('Configuration loaded successfully:', config.port);
// } catch (e) {
// console.error('Application startup failed.');
// }
μ€λͺ :
- `fs` λ° `path` λͺ¨λμ κ°μ Έμ΅λλ€.
- `path.join(__dirname, '..', 'config.json')`μ μ΄μ 체μ μ κ΄κ³μμ΄ νμΌ κ²½λ‘λ₯Ό μμ μ μΌλ‘ ꡬμ±ν©λλ€. `__dirname`μ νμ¬ λͺ¨λμ λλ ν 리λ₯Ό μ 곡ν©λλ€.
- `fs.readFileSync`λ νμΌ λ΄μ©μ λκΈ°μ μΌλ‘ μ½μ΅λλ€. μ₯κΈ° μ€ν νλ‘μΈμ€ λλ λμ λμμ± μ ν리μΌμ΄μ μ κ²½μ° λΉλκΈ° `fs.readFile`μ΄ μ νΈλ©λλ€.
- `JSON.parse`λ JSON λ¬Έμμ΄μ JavaScript κ°μ²΄λ‘ λ³νν©λλ€.
parsedConfig as ServerConfigλ νμ μ΄μ€μ μ λλ€. TypeScript μ»΄νμΌλ¬μκ² `parsedConfig`λ₯Ό `ServerConfig` νμ μΌλ‘ μ²λ¦¬νλλ‘ μ§μν©λλ€. μ΄λ κ°λ ₯νμ§λ§, νμ±λ JSONμ΄ μ€μ λ‘ μΈν°νμ΄μ€λ₯Ό μ€μνλ€λ κ°μ μ μμ‘΄ν©λλ€.- μ€μνκ², νμ μμ±μ λν λ°νμ κ²μ¬λ₯Ό μΆκ°ν©λλ€. TypeScriptλ μ»΄νμΌ νμμ λμμ΄ λμ§λ§, (νμΌκ³Ό κ°μ) λμ λ°μ΄ν°λ μ¬μ ν μλͺ» νμ±λ μ μμ΅λλ€. μ΄λ¬ν λ°νμ κ²μ¬λ κ°λ ₯ν μ ν리μΌμ΄μ μ νμμ μ λλ€.
- νμΌ I/Oλ₯Ό μ²λ¦¬ν λλ νμΌμ΄ μ‘΄μ¬νμ§ μκ±°λ, μ‘μΈμ€ν μ μκ±°λ, μ ν¨νμ§ μμ λ°μ΄ν°λ₯Ό ν¬ν¨ν μ μμΌλ―λ‘ `try...catch`λ₯Ό μ¬μ©ν μ€λ₯ μ²λ¦¬κ° νμμ μ λλ€.
νμΌ κ²½λ‘ λ° λλ ν 리 μμ
TypeScriptλ λλ ν 리 μν λ° νμΌ κ²½λ‘ μ‘°μκ³Ό κ΄λ ¨λ μμ μ μμ μ±λ ν₯μμν¬ μ μμ΅λλ€.
μμ: νμ μμ μ±μ κ°μΆ λλ ν 리μ νμΌ λμ΄
import * as fs from 'fs';
import * as path from 'path';
interface FileInfo {
name: string;
isDirectory: boolean;
size: number; // Size in bytes
createdAt: Date;
modifiedAt: Date;
}
export function listDirectoryContents(directoryPath: string): FileInfo[] {
const absolutePath = path.resolve(directoryPath); // Get absolute path for consistency
const entries: FileInfo[] = [];
try {
const files = fs.readdirSync(absolutePath, { withFileTypes: true });
for (const file of files) {
const filePath = path.join(absolutePath, file.name);
let stats;
try {
stats = fs.statSync(filePath);
} catch (statError) {
console.warn(`Could not get stats for ${filePath}:`, statError);
continue; // Skip this entry if stats can't be retrieved
}
entries.push({
name: file.name,
isDirectory: file.isDirectory(),
size: stats.size,
createdAt: stats.birthtime, // Note: birthtime might not be available on all OS
modifiedAt: stats.mtime
});
}
return entries;
} catch (error) {
console.error(`Failed to read directory ${absolutePath}:`, error);
throw new Error('Directory listing failed.');
}
}
// Example usage:
// try {
// const filesInProject = listDirectoryContents('./src');
// console.log('Files in src directory:');
// filesInProject.forEach(file => {
// console.log(`- ${file.name} (Is Directory: ${file.isDirectory}, Size: ${file.size} bytes)`);
// });
// } catch (e) {
// console.error('Could not list directory contents.');
// }
μ£Όμ κ°μ μ¬ν:
- κ° νμΌ λλ λλ ν 리μ λν΄ λ°ννλ €λ λ°μ΄ν°λ₯Ό ꡬ쑰ννκΈ° μν΄ `FileInfo` μΈν°νμ΄μ€λ₯Ό μ μν©λλ€.
- `path.resolve`λ μ λ κ²½λ‘λ‘ μμ νμ¬ μλ κ²½λ‘ ν΄μκ³Ό κ΄λ ¨λ λ¬Έμ λ₯Ό λ°©μ§ν μ μμ΅λλ€.
- `withFileTypes: true`λ₯Ό μ¬μ©ν `fs.readdirSync`λ `isDirectory()`μ κ°μ μ μ©ν λ©μλκ° μλ `fs.Dirent` κ°μ²΄λ₯Ό λ°νν©λλ€.
- `fs.statSync`λ₯Ό μ¬μ©νμ¬ ν¬κΈ° λ° νμμ€ν¬νμ κ°μ μμΈν νμΌ μ 보λ₯Ό κ°μ Έμ΅λλ€.
- ν¨μ μκ·Έλμ²λ `FileInfo` κ°μ²΄μ λ°°μ΄μ λ°ννλ€κ³ λͺ μμ μΌλ‘ λͺ μνμ¬ μ¬μ©μκ° λͺ ννκ³ νμ μμ νκ² μ¬μ©ν μ μλλ‘ ν©λλ€.
- λλ ν 리 μ½κΈ° λ° νμΌ ν΅κ³ κ°μ Έμ€κΈ° λͺ¨λμ λν κ°λ ₯ν μ€λ₯ μ²λ¦¬κ° ν¬ν¨λ©λλ€.
νμ μμ ν λ¬Έμ μ²λ¦¬λ₯Ό μν λͺ¨λ² μ¬λ‘
κΈ°λ³Έμ μΈ νμ μ΄μ€μ μΈμλ, νΉν μλ‘ λ€λ₯Έ νκ²½μμ μμ νλ κ΅μ νμ μν΄, κ°λ ₯νκ³ μ μ§ κ΄λ¦¬ κ°λ₯ν μμ€ν μ ꡬμΆνλ €λ©΄ νμ μμ ν λ¬Έμ μ²λ¦¬μ λν ν¬κ΄μ μΈ μ λ΅μ μ±ννλ κ²μ΄ μ€μν©λλ€.
1. μμΈν μΈν°νμ΄μ€ λ° νμ μμ©
κ΅¬μ± νμΌ, API μλ΅ λλ μ¬μ©μκ° μμ±ν μ½ν μΈ μ κ°μ μΈλΆ μ λ ₯μ λν΄ λͺ¨λ λ°μ΄ν° ꡬ쑰μ λν μμΈν μΈν°νμ΄μ€λ₯Ό λ§λλ κ²μ μ£Όμ νμ§ λ§μμμ€. μ¬κΈ°μλ λ€μμ΄ ν¬ν¨λ©λλ€.
- μ νλ κ°μ λν μ΄κ±°ν: νΉμ κ° μ§ν©λ§ νμ©ν μ μλ νλ(μ: 'enabled'/'disabled', 'pending'/'completed')μ λν΄ μ΄κ±°νμ μ¬μ©ν©λλ€.
- μ μ°μ±μ μν μ λμ¨ νμ : νλκ° μ¬λ¬ νμ μ νμ©ν μ μλ κ²½μ°(μ: `string | number`) μ λμ¨ νμ μ μ¬μ©νμ§λ§ μΆκ°λ 볡μ‘μ±μ μ μνμμμ€.
- νΉμ λ¬Έμμ΄μ λν 리ν°λ΄ νμ : λ¬Έμμ΄ κ°μ μ νν 리ν°λ΄λ‘ μ νν©λλ€(μ: HTTP λ©μλμ κ²½μ° `'GET' | 'POST'`).
2. λ°νμ μ ν¨μ± κ²μ¬ ꡬν
μ€λͺ ν λ°μ κ°μ΄, TypeScriptμ νμ μ΄μ€μ μ μ£Όλ‘ μ»΄νμΌ μκ° κ²μ¬λ₯Ό μν κ²μ λλ€. μΈλΆ μμ€(νμΌ, API, μ¬μ©μ μ λ ₯)μμ μ 곡λλ λ°μ΄ν°μ κ²½μ°, λ°νμ μ ν¨μ± κ²μ¬λ νμν μ μμ΅λλ€. λ€μκ³Ό κ°μ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©ν©λλ€.
- Zod: TypeScript μ°μ μ€ν€λ§ μ μΈ λ° μ ν¨μ± κ²μ¬ λΌμ΄λΈλ¬λ¦¬μ λλ€. λν μμ ν μ λ ₯λ μ€ν€λ§λ₯Ό μ μνλ μ μΈμ λ°©μμ μ 곡ν©λλ€.
- Yup: κ° νμ± λ° μ ν¨μ± κ²μ¬λ₯Ό μν μ€ν€λ§ λΉλμ λλ€. JavaScript λ° TypeScriptμ μ ν΅ν©λ©λλ€.
- io-ts: 볡μ‘ν μ ν¨μ± κ²μ¬ μλ리μ€μ κ°λ ₯ν μ μλ λ°νμ νμ κ²μ¬ λΌμ΄λΈλ¬λ¦¬μ λλ€.
μ΄λ¬ν λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ©΄ λ°μ΄ν°μ μμ λͺ¨μκ³Ό νμ μ μ€λͺ νλ μ€ν€λ§λ₯Ό μ μν μ μμ΅λλ€. κ·Έλ° λ€μ μ΄λ¬ν μ€ν€λ§λ₯Ό μ¬μ©νμ¬ λ€μ΄μ€λ λ°μ΄ν°λ₯Ό νμ±νκ³ μ ν¨μ±μ κ²μ¬νμ¬ λ°μ΄ν°κ° μ€μνμ§ μλ κ²½μ° λͺ μμ μ€λ₯λ₯Ό λ°μμν¬ μ μμ΅λλ€. μ΄ κ³μΈ΅μ μ κ·Ό λ°©μ(μ»΄νμΌ νμμ TypeScript, λ°νμμ Zod/Yup)μ κ°μ₯ κ°λ ₯ν ννμ μμ μ±μ μ 곡ν©λλ€.
Zodλ₯Ό μ¬μ©ν μμ(κ°λ μ ):
import { z } from 'zod';
import * as fs from 'fs';
// Define a Zod schema that matches our ServerConfig interface
const ServerConfigSchema = z.object({
port: z.number().int().positive(),
hostname: z.string().min(1),
database: z.object({
type: z.enum(['postgres', 'mysql', 'mongodb']),
connectionString: z.string().url() // Example: requires a valid URL format
}),
logging: z.object({
level: z.enum(['debug', 'info', 'warn', 'error']),
filePath: z.string().optional()
})
});
// Infer the TypeScript type from the Zod schema
export type ServerConfigValidated = z.infer;
export function loadConfigWithZod(): ServerConfigValidated {
const rawConfig = fs.readFileSync('config.json', 'utf-8');
const configData = JSON.parse(rawConfig);
try {
// Zod parses and validates the data at runtime
const validatedConfig = ServerConfigSchema.parse(configData);
return validatedConfig;
} catch (error) {
console.error('Configuration validation failed:', error);
throw new Error('Invalid configuration file.');
}
}
3. λΉλκΈ° μμ μ¬λ°λ₯΄κ² μ²λ¦¬
νμΌ μμ μ μ’ μ’ I/O λ°μ΄λμ΄λ©°, νΉν μλ² μ ν리μΌμ΄μ μμ μ΄λ²€νΈ 루νλ₯Ό μ°¨λ¨νμ§ μλλ‘ λΉλκΈ°μ μΌλ‘ μ²λ¦¬λμ΄μΌ ν©λλ€. TypeScriptλ Promises λ° `async/await`μ κ°μ λΉλκΈ° ν¨ν΄μ νλ₯νκ² λ³΄μν©λλ€.
μμ: λΉλκΈ° νμΌ μ½κΈ°
import * as fs from 'fs/promises'; // Use the promise-based API
import * as path from 'path';
import { ServerConfig } from './config.interface'; // Assume this interface exists
const configFilePath = path.join(__dirname, '..', 'config.json');
export async function loadConfigAsync(): Promise<ServerConfig> {
try {
const rawConfig = await fs.readFile(configFilePath, 'utf-8');
const parsedConfig = JSON.parse(rawConfig);
return parsedConfig as ServerConfig; // Again, consider Zod for robust validation
} catch (error) {
console.error(`Failed to load configuration asynchronously from ${configFilePath}:`, error);
throw new Error('Async configuration loading failed.');
}
}
// Example of how to use it:
// async function main() {
// try {
// const config = await loadConfigAsync();
// console.log('Async config loaded:', config.hostname);
// } catch (e) {
// console.error('Failed to start application.');
// }
// }
// main();
μ΄ λΉλκΈ° λ²μ μ νλ‘λμ νκ²½μ λ μ ν©ν©λλ€. `fs/promises` λͺ¨λμ Promise κΈ°λ°μ νμΌ μμ€ν ν¨μλ₯Ό μ 곡νμ¬ `async/await`μ μννκ² ν΅ν©ν μ μμ΅λλ€.
4. μ΄μ 체μ κ° νμΌ κ²½λ‘ κ΄λ¦¬
Node.jsμ `path` λͺ¨λμ νλ«νΌ κ° νΈνμ±μ νμμ μ λλ€. νμ λ€μμ μ¬μ©νμμμ€.
path.join(...): νλ«νΌλ³ κ΅¬λΆ κΈ°νΈλ‘ κ²½λ‘ μΈκ·Έλ¨ΌνΈλ₯Ό κ²°ν©ν©λλ€.path.resolve(...): μΌλ ¨μ κ²½λ‘ λλ κ²½λ‘ μΈκ·Έλ¨ΌνΈλ₯Ό μ λ κ²½λ‘λ‘ λ³νν©λλ€.path.dirname(...): κ²½λ‘μ λλ ν 리 μ΄λ¦μ κ°μ Έμ΅λλ€.path.basename(...): κ²½λ‘μ λ§μ§λ§ λΆλΆμ κ°μ Έμ΅λλ€.
μ΄λ₯Ό μΌκ΄λκ² μ¬μ©νλ©΄ μ ν리μΌμ΄μ μ΄ Windows, macOS λλ Linuxμμ μ€νλλμ§ μ¬λΆμ κ΄κ³μμ΄ νμΌ κ²½λ‘ λ‘μ§μ΄ μ¬λ°λ₯΄κ² μλνλ©°, μ΄λ κΈλ‘λ² λ°°ν¬μ λ§€μ° μ€μν©λλ€.
5. μμ ν νμΌ μ²λ¦¬
TypeScriptλ νμ μ μ€μ μ λμ§λ§, νμΌ κ΄λ¦¬μμμ μ μ©μ κ°μ μ μΌλ‘ 보μμ κ°νν©λλ€.
- μ¬μ©μ μ λ ₯ μ 리: νμΌ μ΄λ¦ λλ κ²½λ‘κ° μ¬μ©μ μ λ ₯μμ νμλ κ²½μ°, λλ ν 리 μν 곡격(μ: `../`)μ λ°©μ§νκΈ° μν΄ νμ μ² μ ν μ 리νμμμ€. TypeScriptμ λ¬Έμμ΄ νμ μ λμμ΄ λμ§λ§, μ 리 λ‘μ§μ΄ ν΅μ¬μ λλ€.
- μ격ν κΆν: νμΌμ μμ±ν λ, μ μ ν νλκ·Έμ λͺ¨λλ₯Ό μ¬μ©νμ¬ `fs.open`μ μ¬μ©νλ©΄ νμΌμ΄ νμν μ΅μ κΆνμΌλ‘ μμ±λ©λλ€.
- μ λ‘λλ νμΌ μ ν¨μ± κ²μ¬: νμΌ μ λ‘λμ κ²½μ°, νμΌ μ ν, ν¬κΈ° λ° μ½ν μΈ λ₯Ό μ격νκ² μ ν¨μ± κ²μ¬ν©λλ€. λ©νλ°μ΄ν°λ₯Ό μ λ’°νμ§ λ§μμμ€. κ°λ₯ν κ²½μ° λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ¬ νμΌ μ½ν μΈ λ₯Ό κ²μ¬ν©λλ€.
6. νμ λ° API λ¬Έμν
κ°λ ₯ν νμ μ΄ μλ κ²½μ°μλ λͺ νν λ¬Έμνλ νΉν κ΅μ νμ νμμ μ λλ€. JSDoc μ£Όμμ μ¬μ©νμ¬ μΈν°νμ΄μ€, ν¨μ λ° λ§€κ°λ³μλ₯Ό μ€λͺ ν©λλ€. μ΄ λ¬Έμλ μ’ μ’ IDE λ° λ¬Έμ μμ± λꡬμμ λ λλ§λ μ μμ΅λλ€.
μμ: TypeScriptλ₯Ό μ¬μ©ν JSDoc
/**
* Represents the configuration for a database connection.
*/
interface DatabaseConfig {
/**
* The type of database (e.g., 'postgres', 'mongodb').
*/
type: 'postgres' | 'mysql' | 'mongodb';
/**
* The connection string for the database.
*/
connectionString: string;
}
/**
* Loads the server configuration from a JSON file.
* This function performs basic validation.
* For stricter validation, consider using Zod or Yup.
* @returns The loaded server configuration object.
* @throws Error if the configuration file cannot be loaded or parsed.
*/
export function loadConfig(): ServerConfig {
// ... implementation ...
}
νμΌ κ΄λ¦¬μ λν κΈλ‘λ² κ³ λ € μ¬ν
κΈλ‘λ² νλ‘μ νΈμμ μμ νκ±°λ λ€μν νκ²½μ μ ν리μΌμ΄μ μ λ°°ν¬νλ κ²½μ°, νμΌ κ΄λ¦¬μ κ΄λ ¨λ λͺ κ°μ§ μμκ° νΉν μ€μν΄μ§λλ€.
κ΅μ ν(i18n) λ° νμ§ν(l10n)
μ ν리μΌμ΄μ μ΄ μ¬μ©μκ° μμ±ν μ½ν μΈ λλ νμ§νκ° νμν ꡬμ±μ μ²λ¦¬νλ κ²½μ°:
- νμΌ λͺ λͺ κ·μΉ: μΌκ΄μ±μ μ μ§ν©λλ€. νΉμ νμΌ μμ€ν λλ λ‘μΊμμ λ¬Έμ λ₯Ό μΌμΌν¬ μ μλ λ¬Έμλ₯Ό μ¬μ©νμ§ λ§μμμ€.
- μΈμ½λ©: ν μ€νΈ νμΌμ μ½κ±°λ μΈ λ νμ UTF-8 μΈμ½λ©μ μ§μ νμμμ€(`fs.readFileSync(..., 'utf-8')`). μ΄κ²μ μ¬μ€μ νμ€μ΄λ©° κ΄λ²μν λ¬Έμλ₯Ό μ§μν©λλ€.
- 리μμ€ νμΌ: i18n/l10n λ¬Έμμ΄μ κ²½μ° JSON λλ YAMLκ³Ό κ°μ ꡬ쑰νλ νμμ κ³ λ €νμμμ€. TypeScript μΈν°νμ΄μ€ λ° μ ν¨μ± κ²μ¬λ λͺ¨λ νμν λ²μμ΄ μ‘΄μ¬νκ³ μ¬λ°λ₯΄κ² νμνλλλ‘ νλ λ° λ§€μ° μ μ©ν©λλ€.
μκ°λ λ° λ μ§/μκ° μ²λ¦¬
νμΌ νμμ€ν¬ν(`createdAt`, `modifiedAt`)λ μκ°λλ₯Ό μ¬μ©νλ©΄ κΉλ€λ‘μΈ μ μμ΅λλ€. JavaScriptμ `Date` κ°μ²΄λ λ΄λΆμ μΌλ‘ UTCλ₯Ό κΈ°λ°μΌλ‘ νμ§λ§, λ€λ₯Έ μ§μμμ μΌκ΄λκ² νννκΈ° μ΄λ €μΈ μ μμ΅λλ€. νμμ€ν¬νλ₯Ό νμν λλ νμ μκ°λλ₯Ό λͺ μνκ±°λ UTCλ‘ νμνμμμ€.
νμΌ μμ€ν μ°¨μ΄
Node.jsμ `fs` λ° `path` λͺ¨λμ λ§μ OS μ°¨μ΄λ₯Ό μΆμννμ§λ§, λ€μ μ¬νμ μΈμ§νμμμ€.
- λμλ¬Έμ ꡬλΆ: Linux νμΌ μμ€ν μ μΌλ°μ μΌλ‘ λμλ¬Έμλ₯Ό ꡬλΆνκ³ , Windows λ° macOSλ μΌλ°μ μΌλ‘ λμλ¬Έμλ₯Ό ꡬλΆνμ§ μμ΅λλ€(ꡬλΆνλλ‘ κ΅¬μ±ν μ μμ). μ½λμμ νμΌ μ΄λ¦μ μΌκ΄λκ² μ²λ¦¬νλμ§ νμΈνμμμ€.
- κ²½λ‘ κΈΈμ΄ μ ν: μ΄μ Windows λ²μ μλ κ²½λ‘ κΈΈμ΄ μ νμ΄ μμμ§λ§, μ΅μ μμ€ν μμλ λ¬Έμ κ° λν©λλ€.
- νΉμ λ¬Έμ: νΉμ μ΄μ 체μ μμ μμ½λκ±°λ νΉλ³ν μλ―Έλ₯Ό κ°λ νμΌ μ΄λ¦μ λ¬Έμλ₯Ό μ¬μ©νμ§ λ§μμμ€.
ν΄λΌμ°λ μ€ν λ¦¬μ§ ν΅ν©
λ§μ μ΅μ μ ν리μΌμ΄μ μ AWS S3, Google Cloud Storage λλ Azure Blob Storageμ κ°μ ν΄λΌμ°λ μ€ν 리μ§λ₯Ό μ¬μ©ν©λλ€. μ΄λ¬ν μλΉμ€λ μ΄λ―Έ μ λ ₯λκ±°λ TypeScriptμ μ½κ² ν΅ν©λ μ μλ SDKλ₯Ό μ 곡νλ κ²½μ°κ° λ§μ΅λλ€. μΌλ°μ μΌλ‘ μ¬λ¬ μ§μ κ΄λ ¨ λ¬Έμ λ₯Ό μ²λ¦¬νκ³ νμΌ κ΄λ¦¬λ₯Ό μν κ°λ ₯ν APIλ₯Ό μ 곡νλ©°, μ΄λ₯Ό μ¬μ©νμ¬ TypeScriptλ₯Ό ν΅ν΄ νμ μμ νκ² μνΈ μμ©ν μ μμ΅λλ€.
κ²°λ‘
TypeScriptλ νμΌ κ΄λ¦¬ λ° λ¬Έμ μ²λ¦¬μ λν νμ μ μΈ μ κ·Ό λ°©μμ μ 곡ν©λλ€. μ»΄νμΌ νμμ νμ μμ μ±μ μ μ©νκ³ κ°λ ₯ν λ°νμ μ ν¨μ± κ²μ¬ μ λ΅κ³Ό ν΅ν©ν¨μΌλ‘μ¨, κ°λ°μλ μ€λ₯λ₯Ό ν¬κ² μ€μ΄κ³ , μ½λ νμ§μ ν₯μμν€λ©°, λ³΄λ€ μμ νκ³ μ λ’°ν μ μλ μ ν리μΌμ΄μ μ ꡬμΆν μ μμ΅λλ€. μΈν°νμ΄μ€λ‘ λͺ νν λ°μ΄ν° ꡬ쑰λ₯Ό μ μνκ³ , μ΄λ₯Ό μ격νκ² μ ν¨μ± κ²μ¬νλ©°, λΉλκΈ° μμ μ μ°μνκ² μ²λ¦¬νλ κΈ°λ₯μ TypeScriptλ₯Ό νμΌμ μ¬μ©νλ λͺ¨λ κ°λ°μμκ² νμμ μΈ λκ΅¬λ‘ λ§λλλ€.
κΈλ‘λ² νμ κ²½μ°, μ΄μ μ΄ μ¦νλ©λλ€. λͺ ννκ³ νμ μμ ν μ½λλ λ³Έμ§μ μΌλ‘ λ μ½κΈ° μ½κ³ μ μ§ κ΄λ¦¬κ° μ©μ΄νμ¬, μλ‘ λ€λ₯Έ λ¬Ένμ μκ°λμμ νμ μ μ΄μ§ν©λλ€. μμΈν μΈν°νμ΄μ€ λ° λ°νμ μ ν¨μ± κ²μ¬μμ νλ«νΌ κ° κ²½λ‘ μ²λ¦¬ λ° μμ ν μ½λ© μμΉμ μ΄λ₯΄κΈ°κΉμ§ μ΄ κ°μ΄λμ μ€λͺ λ λͺ¨λ² μ¬λ‘λ₯Ό μ±νν¨μΌλ‘μ¨, ν¨μ¨μ μ΄κ³ κ°λ ₯ν λΏλ§ μλλΌ μ μΈκ³μ μΌλ‘ νΈν κ°λ₯νκ³ μ λ’°ν μ μλ λ¬Έμ μ²λ¦¬ μμ€ν μ ꡬμΆν μ μμ΅λλ€.
μ€ν κ°λ₯ν ν΅μ°°λ ₯:
- μκ² μμνμμμ€: μ€μν κ΅¬μ± νμΌ λλ μ¬μ©μκ° μ 곡ν λ°μ΄ν° ꡬ쑰λ₯Ό νμ΄ννλ κ²μΌλ‘ μμνμμμ€.
- μ ν¨μ± κ²μ¬ λΌμ΄λΈλ¬λ¦¬ ν΅ν©: λͺ¨λ μΈλΆ λ°μ΄ν°μ κ²½μ°, TypeScriptμ μ»΄νμΌ νμ μμ μ±κ³Ό λ°νμ κ²μ¬λ₯Ό μν΄ Zod, Yup λλ io-tsλ₯Ό νμ΄λ§νμμμ€.
- `path` λ° `fs/promises`λ₯Ό μΌκ΄λκ² μ¬μ©νμμμ€: Node.jsμμ νμΌ μμ€ν μνΈ μμ©μ μν κΈ°λ³Έ μ ν μ¬νμΌλ‘ λ§λμμμ€.
- μ€λ₯ μ²λ¦¬ κ²ν : λͺ¨λ νμΌ μμ μ ν¬κ΄μ μΈ `try...catch` λΈλ‘μ΄ μλμ§ νμΈνμμμ€.
- νμ λ¬Έμν: 볡μ‘ν μΈν°νμ΄μ€μ ν¨μμ λν΄ λͺ νμ±μ μν΄ JSDocμ μ¬μ©νμμμ€.
λ¬Έμ μ²λ¦¬λ₯Ό μν΄ TypeScriptλ₯Ό μμ©νλ κ²μ μννΈμ¨μ΄ νλ‘μ νΈμ μ₯κΈ°μ μΈ κ±΄μ μ±κ³Ό μ±κ³΅μ λν ν¬μμ λλ€.